import ctypes
import inspect
import shutil
import sys
import io
import os
from PIL import Image
from PIL import ImageFile
import pickle

from settings import ENCODING, BASE_DIR
sys.setrecursionlimit(2000000)
def save_obj(obj, name ):
    with open(os.path.join(BASE_DIR, name) + '.pkl', 'wb') as f:
        pickle.dump(obj, f, pickle.HIGHEST_PROTOCOL)
        f.close()

def load_obj(name ):
    with open(os.path.join(BASE_DIR, name) + '.pkl', 'rb') as f:
        pick = pickle.load(f)
        f.close()
        return pick


def _async_raise(tid, exctype):
    """raises the exception, performs cleanup if needed"""
    tid = ctypes.c_long(tid)
    if not inspect.isclass(exctype):
        exctype = type(exctype)
    res = ctypes.pythonapi.PyThreadState_SetAsyncExc(tid, ctypes.py_object(exctype))
    if res == 0:
        raise ValueError("invalid thread id")
    elif res != 1:
        # """if it returns a number greater than one, you're in trouble,
        # and you should call it again with exc=NULL to revert the effect"""
        ctypes.pythonapi.PyThreadState_SetAsyncExc(tid, None)
        raise SystemError("PyThreadState_SetAsyncExc failed")

def compress_image(outfile,jobName ,mb=900, quality=85, k=0.9):
    """不改变图片尺寸压缩到指定大小
    :param outfile: 压缩文件保存地址
    :param mb: 压缩目标，KB
    :param step: 每次调整的压缩比率
    :param quality: 初始压缩比率
    :return: 压缩文件地址，压缩文件大小
    """

    o_size = os.path.getsize(outfile) // 1024
    print(o_size, mb)
    if o_size <= mb:
        return outfile

    ImageFile.LOAD_TRUNCATED_IMAGES = True
    dir, suffix = os.path.splitext(outfile)
    filepath = outfile[:-len(outfile.split('/')[-1])]
    opath = '{}_compress_out'.format(filepath.split('/')[0])+jobName
    try:
        os.mkdir(opath)
    except:
        pass
    outNum =0
    outpath = '{}/'.format(opath)#.split('/')[0]
    outName = outpath + dir.split('/')[-1]

    while o_size > mb:
        im = Image.open(outfile)
        x, y = im.size
        out = im.resize((int(x * k), int(y * k)), Image.ANTIALIAS)
        try:

            outfile = outName + str(outNum) + suffix
            out.save(outfile, quality=quality)
            outNum+=1
            del im#解除占用
        except Exception as e:
            print('out.save', e)
            break
        o_size = os.path.getsize(outfile) // 1024

    compress_path = '{}/_tmp_compress'.format(filepath.split('/')[0])+jobName
    if os.path.exists(compress_path):
        shutil.rmtree(compress_path)
    os.mkdir(compress_path)
    shutil.copy(outfile, compress_path)
    os.rename(compress_path + '/' + outfile.split('/')[-1], compress_path + '/' + (outName + suffix).split('/')[-1])
    shutil.rmtree(outpath)

    return outfile

def unique_copy(local_dir, dest_dir):
    if not os.path.exists(local_dir):
        return;
    for filename in os.listdir(local_dir):
        pathname = os.path.join(local_dir, filename)
        # if os.path.exists(pathname):
        #     pass
        # else:
        print(' unique_copy',pathname, dest_dir)
        destpath = os.path.join(dest_dir, filename)
        if(os.path.isfile(pathname)):

            if os.path.exists(destpath):
                pass
            else:
                print('copy--destpath--',destpath, '+++')
                shutil.copy(pathname, dest_dir)
        else:
            print('dir------')
            newlocal_dir = local_dir + "/" + filename.replace(local_dir, "", 1)
            newdest_dir = dest_dir + "/" + filename.replace(local_dir, "", 1)
            if os.path.exists(destpath):
                pass
            else:
                print('dest_dir------', dest_dir)
                #print('copy------', dest_dir+"/"+filename)
                # shutil.copy(pathname, dest_dir)
                os.makedirs(dest_dir+"/"+filename)
            unique_copy(newlocal_dir, newdest_dir)